package com.google.io.lastcall.gwt.countdownclock.client;

public class MatrixGrid {
	private char[][] grid;
	private int[] start;
	private int[] stop;
	private int rows;
	private int columns;
	private char mainChar;
	private static final double chanceOfAdding=0.75;
	private static final double chanceOfChanging=0.5;
	private static final double chanceOfCreating=0.25;
	private static final double chanceOfMainNumber=0.1;
	private static final double chanceOfStopping=0.005;
	public boolean[] stopped;
	public double[] SPEEDS;
	private static final double CHANGE_SPEED=0.001;
	public MatrixGrid(int column,int row,char myChar) {
		rows=row;
		columns=column;
		mainChar=myChar;
		grid=new char[columns][];
		start=new int[columns];
		stop=new int[columns];
		SPEEDS=new double[columns];
		for(int i=0;i<columns;i++) {
			SPEEDS[i]=Math.random()/2;
		}
		stopped=new boolean[columns];
	}
	public void changeChar(char newChar) {
		mainChar=newChar;
	}
	public void run() {
		for(int i=0;i<grid.length;i++) {
			if(stopped[i]) {
				if(Math.random()<(chanceOfStopping*2)) {
					stopped[i]=false;
				}
				continue;
			}
			if(Math.random()<chanceOfStopping) {
				stopped[i]=true;
			}
			if(Math.random()<CHANGE_SPEED) {
				SPEEDS[i]=Math.random()/2;
			}
			if(grid[i]!=null) {
				if(stop[i]>=columns) {
					grid[i]=null;
				} else {
					if(Math.random()<=SPEEDS[i]) continue;
					if(stop[i]>0&&start[i]<grid[i].length&&Math.random()<chanceOfAdding) {
						stop[i]--;
						grid[i][stop[i]]=(char) (Math.floor(Math.random()*255)+1);
					}
					for(int j=(grid[i].length-2);j>=0;j--) {
						grid[i][j+1]=grid[i][j];
					}
					for(int j=0;j<grid[i].length;j++) {
						if(j==start[i]||grid[i][j]==0||grid[i][j]==mainChar) continue;
						if(Math.random()<chanceOfChanging) {
							if(Math.random()<chanceOfMainNumber) {
								grid[i][j]=mainChar;
							} else {
								grid[i][j]=(char) (Math.floor(Math.random()*255)+1);
							}
						}
					}
					start[i]++;
					stop[i]++;
				}
			} else {
				if(Math.random()<chanceOfCreating) {
					grid[i]=new char[rows];
					start[i]=0;
					stop[i]=0;
					grid[i][0]=mainChar;
				}
			}
		}
	}
	public MatrixNode[][] iterator() {
		MatrixNode[][] mn=new MatrixNode[columns][rows];
		for(int i=0;i<columns;i++) {
			if(grid[i]!=null) {
				for(int j=stop[i];j<grid[i].length&&j<=start[i];j++) {
					if(grid[i][j]==0) continue;
					int offset=start[i]-j;
					mn[i][j]=new MatrixNode(i,j,grid[i][j],"#"+toHexRB(offset)+"0"+toHex(offset)+"0"+toHexRB(offset)+"0",grid[i][j]==mainChar);
				}
			}
		}
		return mn;
	}
	public String toHex(int offset) {
		switch(offset) {
		case 0:
			return "E";
		case 1:
			return "E";
		case 2:
			return "F";
		case 3:
			return "D";
		case 4:
			return "B";
		case 5:
			return "9";
		case 6:
			return "6";
		default:
			return "3";
		}
	}
	public String toHexRB(int offset) {
		switch(offset) {
		case 0:
			return "E";
		case 1:
			return "2";
		case 2:
			return "5";
		case 3:
			return "3";
		case 4:
			return "2";
		case 5:
			return "1";
		case 6:
			return "0";
		default:
			return "0";
		}
	}
}